package while_lang.ast;

import java.util.*;

import while_lang.semantics.State;

/** Nodo del AST que representa un array definido por extensión.
 *  @author Leonardo Val
 */
public class ArrayExp extends Exp {	
	public final Exp[] expressions;
	
	public ArrayExp(Exp... expressions) {
		this.expressions = expressions;
	}
	public ArrayExp(List<Exp> expressions) {
		this.expressions = expressions.toArray(new Exp[expressions.size()]);
	}

	@Override public String unparse() {
		StringBuilder result = new StringBuilder("[");
		if (expressions.length > 0) {
			result.append(expressions[0].unparse());
		}
		for (int i = 1; i < expressions.length; i++) {
			result.append(", ").append(expressions[i].unparse());
		}
		return result.toString() +"]";
	}

	@Override public Object evaluate(State state) {
		Object[] aux = new Object[this.expressions.length];
		for (int i = 0; i < aux.length; i++) {
			aux[i] = this.expressions[i].evaluate(state);
		}
		return aux;
	}
	
	public static ArrayExp generate(Random random, int min, int max) {
		int count = random.nextInt(5);
		Exp[] expressions = new Exp[count];
		for (int i = 0; i < count; i++) {
			expressions[i] = Exp.generate(random, min-1, max-1);
		}
		return new ArrayExp(expressions);
	}
	
	@Override public String toString() {
		return "ArrayExp("+ Arrays.toString(expressions) +")";
	}

	@Override public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + Arrays.hashCode(expressions);
		return result;
	}

	@Override public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		ArrayExp other = (ArrayExp) obj;
		if (!Arrays.equals(expressions, other.expressions))
			return false;
		return true;
	}
	
}
